// Copyright (C) 1991-2013 Altera Corporation
// Your use of Altera Corporation's design tools, logic functions 
// and other software and tools, and its AMPP partner logic 
// functions, and any output files from any of the foregoing 
// (including device programming or simulation files), and any 
// associated documentation or information are expressly subject 
// to the terms and conditions of the Altera Program License 
// Subscription Agreement, Altera MegaCore Function License 
// Agreement, or other applicable license agreement, including, 
// without limitation, that your use is for the sole purpose of 
// programming logic devices manufactured by Altera and sold by 
// Altera or its authorized distributors.  Please refer to the 
// applicable agreement for further details.

// *****************************************************************************
// This file contains a Verilog test bench template that is freely editable to  
// suit user's needs .Comments are provided in each section to help the user    
// fill out necessary details.                                                  
// *****************************************************************************
// Generated on "04/13/2024 16:06:39"
                                                                                
// Verilog Test Bench template for design : spi
// 
// Simulation tool : ModelSim (Verilog)
// 

`timescale 1 ps/ 1 ps
module tb_spi();
// constants                                           
// general purpose registers
reg eachvec;
// test vector input registers
reg clk;
reg csen=1'b1;
reg done=1'b1;
reg [7:0] tx_data=0;
reg tx_en;
// wires                                               
wire [7:0]  rx_data;
wire rx_en;
wire sck;
wire sdi;
wire scs;
wire tx_req;
reg  rd_fifo=1'b0;

reg [7:0]   apb_pwdata=0;
reg [7:0]   apb_pwdata_r=0;
reg [0:0]   wen=1'b0;
reg [15:0]  apb_paddr=0;
reg [0:0]   tx_fifo_wreq=1'b0;
wire[0:0]   tx_fifo_empty;
wire[7:0]   tx_fifo_q;
reg [31:0]   apb_prdata=0;
wire[7:0]   rx_fifo_q;
wire[9:0]   usedw;
reg [0:0]   rx_fifo_req=1'b0;
reg [0:0]   ren=1'b0;
reg [0:0]   tx_fifo_rdreq=1'b0;
reg [0:0]   tx_fifo_rdreq_r=1'b0;
reg [7:0]   sdocnt=0;   
reg [2:0]  tx_fifo_empty_r=3'b111;

reg [0:0]  rx_fifo_wen=1'b0;
reg [7:0]  rx_fifo_data=0;
reg [0:0]  rx_fifo_wen_r=1'b0;
reg [7:0]  rx_fifo_data_r=0;



parameter CLK_CYCLE = 125;

always #(CLK_CYCLE/2) clk = ~clk;


initial                                                
begin  
clk = 1'b0;                                     
#10000;                                     
$display("Running testbench");                       
end    
  
always                                                                
begin                                                                                                                        
@eachvec;                                                                                          
end   

	
always@(posedge clk)                           
begin
  apb_paddr <= apb_paddr+1'b1;
  apb_pwdata<= apb_pwdata+1'b1;
end

always@(posedge clk)                           
begin
  if(apb_paddr<=125)
    wen <= 1'b1;
  else
    wen <= 1'b0;
end
//---------------------------------------------
//-- 发送数据fifo
//---------------------------------------------
tx_fifo tx_fifo_inst(
	.clock      (clk          ),
	.data       (apb_pwdata_r ),
	.rdreq      (tx_fifo_rdreq),
	.wrreq      (tx_fifo_wreq ),
	.empty      (tx_fifo_empty),
	.q          (tx_fifo_q    ));
	
always@(posedge clk)                            //-fifo空延拍                  
begin
  tx_fifo_empty_r <= {tx_fifo_empty_r[1:0],tx_fifo_empty};
end

	
always@(posedge clk)                            //--fifo 写使能
begin
  if((wen==1'b1) && (apb_paddr[15]==1'b0))             
    tx_fifo_wreq <= 1'b1;
  else
    tx_fifo_wreq <= 1'b0;
end

always@(posedge clk)                            //--fifo写数据
begin
    apb_pwdata_r <= apb_pwdata[7:0];
end

always@(posedge clk)                            //--fifo读使能             
begin
  if((tx_req==1'b1) && (tx_fifo_empty==1'b0))
    tx_fifo_rdreq <= 1'b1;
  else
    tx_fifo_rdreq <= 1'b0;
end

always@(posedge clk)                           
begin
  tx_fifo_rdreq_r <= tx_fifo_rdreq;
end

//---------------------------------------------
//-- 接收数据fifo
//---------------------------------------------
rx_fifo rx_fifo_inst(
	.clock      (clk           ),
	.data       (rx_fifo_data_r),
	.rdreq      (rx_fifo_req   ),
	.wrreq      (rx_fifo_wen_r ),
	.q          (rx_fifo_q     ),
	.usedw      (usedw         )
);

always@(posedge clk)                           
begin
  if((apb_paddr[15]==1'b0)&&(ren==1'b1))
    rx_fifo_req <= ren;
end
always@(posedge clk)                           
begin
  rx_fifo_wen    <= rx_en;
  rx_fifo_data   <= rx_data;
  rx_fifo_wen_r  <= rx_fifo_wen;
  rx_fifo_data_r <= rx_fifo_data;
end
always@(posedge clk)                           
begin
  if((apb_paddr[15]==1'b0)&&(ren==1'b1))                               //-读fifo数据
    apb_prdata <= {24'd0,rx_fifo_q};
  else if((apb_paddr[15]==1'b1)&&(apb_paddr[1:0]==2'b00)&&(ren==1'b1)) //-读数据格式低8位
    apb_prdata <= {22'd0,usedw};
end


//---------------------------------------------
//-- spi
//---------------------------------------------
                    
spi i1 (
	.clk(clk),
	.csen(csen),
	.rx_data(rx_data),
	.rx_en(rx_en),
	.scs(scs),
	.sck(sck),
	.sdi(sdi),
	.sdo(sdi),
	.tx_data(tx_data),
	.tx_en(tx_en),
	.tx_req(tx_req)
);

always@(posedge clk)                          //-csen                   
begin
  csen <= tx_fifo_empty_r[2];
end

always@(posedge clk)                           
begin
  tx_en   <= tx_fifo_rdreq_r;
  tx_data <= tx_fifo_q;
end

always@(posedge clk)                           
begin
  if((tx_en)&&(tx_fifo_empty==1'b1))
    done <= 1'b1;
  else if(tx_fifo_empty==1'b0)
    done <= 1'b0;
end
assign sdo = sdi;


endmodule

